package com.swind.fast.modules.app.railway.project.service.impl;

import com.swind.fast.common.system.base.service.impl.SwindServiceImpl;
import com.swind.fast.modules.app.railway.project.entity.RailwayProject;
import com.swind.fast.modules.app.railway.project.entity.RailwayProjectOperationLog;
import com.swind.fast.modules.app.railway.project.mapper.RailwayProjectMapper;
import com.swind.fast.modules.app.railway.project.service.IRailwayProjectService;
import com.swind.fast.modules.system.entity.SysUser;
import com.swind.fast.common.system.vo.LoginUser;

import com.swind.fast.modules.system.service.ISysUserService;
import com.swind.fast.modules.app.railway.project.entity.RailwayProjectWorkman;
import com.swind.fast.modules.app.railway.project.service.IRailwayProjectWorkTaskService;
import com.swind.fast.modules.app.railway.project.service.IRailwayProjectWorkmanService;
import com.swind.fast.modules.app.railway.project.service.IRailwayProjectOperationLogService;
import com.swind.fast.common.util.oConvertUtils;
import com.swind.fast.modules.app.railway.project.vo.RailwayProjectVo;
import com.swind.fast.modules.app.railway.project.vo.RailwayProjectStatisticVo;
import com.swind.fast.modules.app.railway.project.vo.RailwayDataManagementStatisticVo;
import com.swind.fast.modules.app.railway.project.constant.ProjectStatusEnum;
import com.swind.fast.modules.app.railway.project.vo.RailwayProjectStatusVo;
import com.swind.fast.modules.app.railway.project.event.ProjectStatusEvent;

import org.apache.shiro.SecurityUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.List;
import java.util.Map;
import java.util.ArrayList;

import lombok.extern.slf4j.Slf4j;

/**
 * @Description: 项目
 */
@Slf4j
@Service
public class RailwayProjectServiceImpl extends SwindServiceImpl<RailwayProjectMapper, RailwayProject> implements IRailwayProjectService {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IRailwayProjectWorkTaskService railwayProjectWorkTaskService;

    @Autowired
    private IRailwayProjectWorkmanService railwayProjectWorkmanService;

    @Autowired
    private IRailwayProjectOperationLogService railwayProjectOperationLogService;

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void saveMain(RailwayProject railwayProject) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String orgCode = user.getOrgCode();

        railwayProject.setStatus(ProjectStatusEnum.ONGOING.getValue());
        railwayProject.setOrgCode(orgCode);
        this.save(railwayProject);

        String projectId = railwayProject.getId();
        String leaderId = railwayProject.getLeaderId();
        RailwayProjectWorkman workman = new RailwayProjectWorkman();
        workman.setProjectId(projectId);
        workman.setUserId(leaderId);
        workman.setPosition(1); // 项目负责人
        railwayProjectWorkmanService.save(workman);

        String memo = "创建项目";
        String createBy = user.getRealname();
        RailwayProjectOperationLog operationLog = new RailwayProjectOperationLog(projectId, 1, 1, memo, createBy);
        railwayProjectOperationLogService.save(operationLog);
    }

    @Override
    public RailwayProject getUserSpecificProjects(RailwayProject railwayProject) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String orgCode = user.getOrgCode();
        String userId = user.getId();
        railwayProject.setOrgCode(orgCode);
        Integer userCategory = user.getUserCategory();
        if (userCategory != 1) { // 非管理员
            List<String> projectIds = railwayProjectWorkmanService.getProjectIdsByUserId(userId);
            String strIds = "," + String.join(",", projectIds);
            railwayProject.setId("in " + strIds);
        }

        return railwayProject;
    }

    public RailwayProjectVo getProjectById(String id) {
        RailwayProject project = this.getById(id);
        RailwayProjectVo retProject = oConvertUtils.entityToModel(project, RailwayProjectVo.class);

        if (project != null) {
            List<String> listIds = new ArrayList();
            listIds.add(project.getOwnerId());
            listIds.add(project.getLeaderId());

            QueryWrapper<SysUser> markQueryWrapper = new QueryWrapper<SysUser>().select("id", "realname", "phone").in("id", listIds);
            List<SysUser> listUsers = sysUserService.list(markQueryWrapper);

            for (SysUser user : listUsers) {
                if (!oConvertUtils.isEmpty(project.getOwnerId()) && project.getOwnerId().equals(user.getId())) {
                    retProject.setOwnerPhone(user.getPhone());
                    retProject.setOwnerName(user.getRealname());
                }
                if (!oConvertUtils.isEmpty(project.getLeaderId()) && project.getLeaderId().equals(user.getId())) {
                    retProject.setLeaderPhone(user.getPhone());
                    retProject.setLeaderName(user.getRealname());
                }
            }
        }

        return retProject;
    }

    public RailwayProjectStatisticVo getProjectStatistic() {

        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String orgCode = user.getOrgCode();
        String userId = user.getId();
        Integer userCategory = user.getUserCategory();
        QueryWrapper<RailwayProject> queryWrapper;
        if (userCategory != 1) { // 非管理员
            List<String> projectIds = railwayProjectWorkmanService.getProjectIdsByUserId(userId);
            queryWrapper = new QueryWrapper<RailwayProject>().select("status, count(id) as total").eq("org_code", orgCode).in("id", projectIds).groupBy("status");
        } else {
            queryWrapper = new QueryWrapper<RailwayProject>().select("status, count(id) as total").eq("org_code", orgCode).groupBy("status");
        }
        List<Map<String, Object>> listMap = this.listMaps(queryWrapper);
        log.info("listMap: {}", listMap);
        RailwayProjectStatisticVo statistic = new RailwayProjectStatisticVo("0", "0", "0", "0");

        for (Map<String, Object> item : listMap) {
            String status = String.valueOf(item.get("status"));
            String total = String.valueOf(item.get("total"));
            switch (status) {
                case "1" :
                    statistic.setOngoing(total);
                    break;
                case "2" :
                    statistic.setChecking(total);
                    break;
                case "4" :
                    statistic.setApproving(total);
                    break;
                case "5" :
                    statistic.setFinished(total);
                    break;
                default:
                    break;
            }
        }
        return statistic;
    }

    public RailwayDataManagementStatisticVo getDataManagementStatistic(String projectId) {
        RailwayDataManagementStatisticVo statistic = railwayProjectWorkTaskService.getWorkTaskStatisticByProjectId(projectId);
        return statistic;
    }

    // public void updateProjectStatus(String projectId, String status) {
    //     LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
    //     String userRealname = user.getRealname();
    //     RailwayProjectStatusVo projectStatus = new RailwayProjectStatusVo(projectId, userRealname, ProjectStatusEnum.getByValue(status));
    //     applicationContext.publishEvent(new ProjectStatusEvent(projectStatus));
    // }

    public void updateProjectStatus(RailwayProjectOperationLog operation) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userRealname = user.getRealname();
        String projectId = operation.getProjectId();
        String status = String.valueOf(operation.getToStatus());
        String memo = operation.getMemo();
        log.info("operation: {}", operation);
        RailwayProjectStatusVo projectStatus = new RailwayProjectStatusVo(projectId, userRealname, memo, ProjectStatusEnum.getByValue(status));
        log.info("operation2: {}", projectStatus);
        applicationContext.publishEvent(new ProjectStatusEvent(projectStatus));
    }

    public void deleteMainById(String id) {
        this.removeById(id);

        QueryWrapper<RailwayProjectWorkman> wqueryWrapper = new QueryWrapper<RailwayProjectWorkman>().eq("project_id", id);
        railwayProjectWorkmanService.remove(wqueryWrapper);

        QueryWrapper<RailwayProjectOperationLog> oqueryWrapper = new QueryWrapper<RailwayProjectOperationLog>().eq("project_id", id);
        railwayProjectOperationLogService.remove(oqueryWrapper);
    }

    public List<RailwayProject> getProjectByOrgCode(String startDate, String endDate) {
        return this.getProjectByOrgCode(null, startDate, endDate);
    }

    public List<RailwayProject> getProjectByOrgCode(String orgCode, String startDate, String endDate) {
        if (oConvertUtils.isEmpty(orgCode)) {
            LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            orgCode = user.getOrgCode();
        }

        QueryWrapper<RailwayProject> queryWrapper;
        if (!oConvertUtils.isEmpty(startDate)) {
            queryWrapper = new QueryWrapper<RailwayProject>().eq("org_code", orgCode).ge("create_time", startDate);
            if (!oConvertUtils.isEmpty(endDate)) {
                queryWrapper = new QueryWrapper<RailwayProject>().eq("org_code", orgCode).ge("create_time", startDate).le("create_time", endDate);
            }
        } else {
            queryWrapper = new QueryWrapper<RailwayProject>().eq("org_code", orgCode);
        }

        List<RailwayProject> listProject = this.list(queryWrapper);
        return listProject;
    }
}
